<template>
  <div class="header-search" :class="{ show: isShow }">
    <svg-icon
      class="search-icon"
      icon="search"
      @click.stop="onShowClick"
    ></svg-icon>
    <el-select
      ref="headerSearchSelectRef"
      class="header-search-select"
      v-model="search"
      filterable
      default-first-option
      remote
      placeholder="Search"
      :remote-method="querySearch"
      @change="onSelectChange"
    >
      <el-option
        v-for="option in searchOptions"
        :key="option.item.path"
        :label="option.item.title.join(' > ')"
        :value="option.item"
      ></el-option>
    </el-select>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { privateRoutes } from '@/router'
import Fuse from 'fuse.js'
import { generateRoutes } from './fuseData'

const isShow = ref(false) // 控制输入框
const search = ref('') // 搜索值
const searchOptions = ref([]) // 搜索结果

// 模糊搜索的路由数据源
const searchPool = computed(() => generateRoutes(privateRoutes))

// 模糊搜索
const fuse = new Fuse(searchPool.value, {
  // 是否按照优先级进行排序
  shouldSort: true,
  // 匹配长度超过这个值的才会被认为是匹配的
  minMatchCharLength: 1,
  // 将被搜搜的建列表，这支持嵌套路径，加权搜索、在字符串和对象数组中搜索
  // name：搜索的值
  // weight：对应的权重
  keys: [
    { name: 'title', weight: 0.7 },
    { name: 'path', weight: 0.4 }
  ]
})

// 点击search图标
const onShowClick = () => (isShow.value = !isShow.value)

// select
const querySearch = (keyword) => {
  searchOptions.value = keyword == '' ? [] : fuse.search(keyword)
  // console.log('querySearch', keyword, fuse.search(keyword))
}
// select 选中
const router = useRouter()
const onSelectChange = (path) => {
  router.push(path)
  onClose()
}

// 关闭 search 的处理事件
const headerSearchSelectRef = ref(null)
const onClose = () => {
  headerSearchSelectRef.value.blur()
  isShow.value = false
  searchOptions.value = []
}

/**
 * 监听 search 打开，处理 close 事件
 */
watch(isShow, (val) => {
  if (val) {
    document.body.addEventListener('click', onClose)
  } else {
    document.body.removeEventListener('click', onClose)
  }
})
</script>

<style lang="scss" scoped>
.header-search {
  font-size: 0 !important;
  .search-icon {
    cursor: pointer;
    font-size: 18px;
    vertical-align: middle;
  }

  ::v-deep {
    .el-select .el-input.is-focus .el-input__wrapper {
      box-shadow: 0 0 0 0 !important;
    }
  }
  .header-search-select {
    font-size: 18px;
    transition: width 0.2s;
    width: 0;
    overflow: hidden;
    background: transparent;
    border-radius: 0;
    display: inline-block;
    vertical-align: middle;

    ::v-deep {
      .el-input__wrapper {
        box-shadow: 0 0 0 0 !important;
      }
      .el-input__inner {
        border-radius: 0;
        border: 0;
        padding-left: 0;
        padding-right: 0;
        box-shadow: none !important;
        border-bottom: 1px solid #d9d9d9;
        vertical-align: middle;
      }
    }

    &:hover {
      ::v-deep {
        .el-input__wrapper {
          box-shadow: 0 0 0 0 !important;
        }
      }
    }
  }
  &.show {
    .header-search-select {
      width: 210px;
      margin-left: 10px;
    }
  }
}
</style>
